package com.fmatos.amazingwallpapers.downloader;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.fmatosqg.gatherimages.backgroundmanager.BackgroundManagerFactory;
import com.fmatosqg.gatherimages.configuration.DownloaderConfiguration;
import com.fmatosqg.gatherimages.downloader.ImageDownloader;
import com.fmatosqg.gatherimages.downloader.nasa.NasaPictureOfTheDayDownloader;
import com.fmatosqg.gatherimages.downloader.ninegag.NineGagDownloader;
import com.fmatosqg.gatherimages.downloader.pinterest.PinterestFeed;
import com.fmatosqg.gatherimages.downloader.utils.DownloaderException;
import com.fmatosqg.gatherimages.downloader.utils.DownloaderHelper;


/**
 * Downloads a photo in the background and puts it in the cache
 * @author fabio.dematos
 *
 */

public class WallpaperCache extends AsyncTask<String, Integer, Bitmap> {

	private TextView edit;
	private ImageView image;
	private Context context;
	private DownloaderConfiguration configuration;
	private LinkedList<String> cachedFiles;

	public WallpaperCache(TextView edit, ImageView image, Context context) {
		super();
		this.edit = edit;
		this.image = image;
		this.context = context;
	}
	
	public List<String> getCachedImages() {
		return cachedFiles;
	}
	
	// -------------  abstract methods implementation 
	@Override
	protected Bitmap doInBackground(String... params) {

		ImageDownloader testedDownloader = downloadImage();
			
		downloadAllPhotos(testedDownloader);
		
		return loadImageFromCache(cachedFiles.getFirst());
	}
	

	
	protected void onPostExecute(Bitmap bm) {
		
		edit.setText("Download Done");

		image.setImageBitmap(bm);

	}
	
	// ----- HELPERS 

	private DownloaderConfiguration getConfiguration() {
		if (configuration == null ) {
			configuration = new DownloaderConfiguration(new Properties());
		}
		
		return configuration;
	}
	
	/**
	 * Requires ACCESS_NETWORK_STATE permission
	 * @return
	 */
	public boolean isNetworkAvailable() {
		ConnectivityManager cm = (ConnectivityManager) 
				context.getSystemService(context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = cm.getActiveNetworkInfo();
		// if no network is available networkInfo will be null
		// otherwise check if we are connected
		if (networkInfo != null && networkInfo.isConnected()) {
			return true;
		}
		return false;
	} 
	
	private String numberedCachedImage(int i) {
		
		String folder = BackgroundManagerFactory.getAndroidManager().getGalleryFolderPath();
		
		return folder + "/image" + i + ".jpg";
	}

	
	// ------- business logic
	
	private ImageDownloader downloadImage() {

		ImageDownloader downloader;
		
//		downloader = new PinterestFeed();
//		downloader = new NineGagDownloader();
		downloader = new NasaPictureOfTheDayDownloader();
		
		Log.i("Tutorial","Fetch urls from " + downloader.getDownloaderName());

		String url = null;
		try {
			url =  downloader.getRandomPhotoUrl(getConfiguration());
			Log.i("Tutorial","got url " + url);

			return downloader;
		} catch (DownloaderException e) {
			e.printStackTrace();
		} catch (RuntimeException e) {
			Log.e("Tutorial", "failed retrieving url from provider, exception = " + e.getMessage());
		}

		return downloader;
	}


	private void downloadAllPhotos(ImageDownloader testedDownloader) {

		List<String> album = testedDownloader.getRandomAlbum(getConfiguration());

		cachedFiles = new LinkedList<String>();

		int count = 0;
		for ( String url : album) {
			String cachedFilename =  numberedCachedImage(count++);
			try {
				downloadImageToCache(url, cachedFilename);
				cachedFiles.add(cachedFilename);
				break; // TODO this is for testing
			} catch (DownloaderException e) {
				e.printStackTrace();
			}

		}
		
		if ( cachedFiles.size() == 0 ) {
			Log.i("Tutorial", "Overriding null photo with schoenberg");
			String url =  "http://0.tqn.com/y/musiced/1/L/6/4/ArnoldSchoenberg.jpg";
			
			String cachedFilename =  numberedCachedImage(0);
			try {
				downloadImageToCache(url, cachedFilename);
				cachedFiles.add(cachedFilename);
			} catch (DownloaderException e) {
				e.printStackTrace();
			}

		}

	}

	private void downloadImageToCache(String url,String filename) throws DownloaderException {
		
		if ( ! isNetworkAvailable() )
			return;
		
		if( url == null) {
			Log.i("Tutorial", "got null url, wont download");
			return;
		}

		Log.i("Tutorial", "Going to download url " + url);
		DownloaderHelper.downloadUrlToAbsoluteFilepath(url, filename, getConfiguration());
		Log.i("Tutorial", "finished " + url);
		
	}

	// move this to a separate class
	@Deprecated
	private Bitmap loadImageFromCache(String filePath) {

		InputStream is;
		Bitmap bm =null;
		try {
			is = new FileInputStream(filePath);
			BufferedInputStream bis = new BufferedInputStream(is);
			bm = BitmapFactory.decodeStream(bis);
			is.close();

		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		if ( bm == null) {
			Log.i("Tutorial", "Couldn't get bitmap for file " + filePath);
		}
		return bm;
	}

	/**
	 * Gets an image from internet url.
	 * @param url
	 * @return
	 */
//	@Deprecated
//	private Bitmap getImageBitmap(String url) {
//
//		if ( ! isNetworkAvailable() )
//			return null;
//		
//		if( url == null) {
//			Log.i("Tutorial", "got null url, wont download");
//			return null;
//		}
//
//		Bitmap bm = null;
//		try {
//			Log.i("Tutorial" , "I'm going to download an image");
//			URL aURL = new URL(url);
//			URLConnection conn = aURL.openConnection();
//			conn.connect(); // hangs here
//			InputStream is = conn.getInputStream();
//			BufferedInputStream bis = new BufferedInputStream(is);
//			bm = BitmapFactory.decodeStream(bis);
//			bis.close();
//			is.close();
//			Log.i("Tutorial","I'm finished downloading an image");
//		} catch (IOException e) {
//			Log.e("HEY!", "Error getting bitmap", e);
//		}
//
//		Log.i("Tutorial"," Got your image here");
//		return bm;
//	}



}